from math import e
from re import L
import requests
import hashlib
import time
from BloodSpiderModel.spider_tools import common_utils, file_operate




class DaiLianTongSpider:
    def __init__(self):
        # 代练通基础url
        self.dailiantong_base_url = "https://server.dailiantong.com.cn/API/AppService.ashx"
        self.spider_common_utils = common_utils.GeneralToolkit()
        self.file_operate = file_operate.FileOperate()
        self.auth_config = self.file_operate.json_format(self.file_operate.read_file("SpiderFile/DaiLianTong/config.json"), is_json=True)
        self.headers = self.spider_common_utils.get_headers(ua_device_type="mobile")
        self.headers["Referer"] = 'https://m.dailiantong.com/'
        self.headers["Origin"] = 'https://m.dailiantong.com'

    
    def get_dict_values(self, input_dict):
        """
        从字典中提取所有值并返回一个列表

        参数:
            input_dict: 输入的字典

        返回:
            list: 包含字典中所有值的列表
        """
        # 检查输入是否为字典类型
        if not isinstance(input_dict, dict):
            raise TypeError("输入必须是一个字典")

        # 提取字典中的所有值并返回列表
        return list(input_dict.values())

    # 加密参数
    def md5_encrypt(self, params, e="LevelOrderList",  Token="",
                    SignKey="9c7b9399680658d308691f2acad58c0a"):
        """
        对输入字符串进行MD5加密，返回小写的32位加密结果

        参数:
            input_str: 需要加密的字符串

        返回:
            str: 小写的32位MD5加密结果
        """
        input_str = "".join(SignKey + e + "".join(self.get_dict_values(params)) + Token)
        # 创建md5对象
        md5_obj = hashlib.md5()

        # 如果输入不是bytes类型，需要先编码
        if isinstance(input_str, str):
            input_str = input_str.encode('utf-8')

        # 更新md5对象
        md5_obj.update(input_str)

        # 获取加密结果并返回小写的32位十六进制字符串
        return md5_obj.hexdigest()


    # 获取认证token
    def get_auth_token(self, mobile="19295757544", password="123456"):
        params = {
            'Action': 'UserTipForChangePass',
        }

        data = {
            'LoginID': mobile,
            'UserID': '0',
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"])
        
        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()

        params['Action'] = "GoHome"

        # 密码加密逻辑: 对password进行md5加密，然后拿md5加密结果在加上 response['LoginID'] 在进行一次md5加密
        data = {
            'LoginID': response['LoginID'],
            'Pass': self.spider_common_utils.md5_encrypt( self.spider_common_utils.md5_encrypt(password) + response['LoginID']),
            'OS': 'WebApp',
            'verifystr': '',
            'HD': '',
            'Channels': 'web',
            'UserID': '0',
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"])

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        return response


    # 获取用户信息 UserInfoList
    def UserInfoList(self, UserID, Token):
        params = {
            'Action': 'UserInfoList',
        }

        data = {
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        return response


    # 获取游戏单子 LevelOrderList
    def LevelOrderList(self, Price_Str, UserID, Token, SearchStr=""):
        """
        获取游戏单子 LevelOrderList
        参数:
            Price_Str: 价格范围，例如 "1_20" 表示 1-20 级
            UserID: 用户ID
            Token: 认证token
            SearchStr: 搜索字符串，默认空字符串
        返回:
            dict: 游戏单子 LevelOrderList 响应数据
        
        注意:
            1. 价格范围 Price_Str 格式为 "1_20" 表示 1-20 元范围的全部订单
            2. SearchStr 为空时表示查询所有订单, 如果不为空就搜索指定关键词单子，如果没有就返回空列表
        """
        params = {
            'Action': 'LevelOrderList',
        }

        data = {
            'IsPub': '1',
            'GameID': '107',
            'ZoneID': '0',
            'ServerID': '0',
            'SearchStr': SearchStr,
            'STier': '',
            'ETier': '',
            'Sort_Str': '',
            'PageIndex': '1',
            'PageSize': '20',
            'Price_Str': Price_Str,
            'PubCancel': '0',
            'SettleHour': '0',
            'FilterType': '1',
            'PGType': '0',
            'Focused': '-1',
            'OrderType': '0',
            'PubRecommend': '0',
            'AcceptLevel': 'C',
            'Score1': '0',
            'Score2': '0',
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        if response["RecordCount"] == 0:
            response["code"] = 1
        else:
            response["code"] = 0
        return response

    # 获取游戏单子详情 LevelOrderDetail
    def LevelOrderDetail(self, OrderID, UserID, Token):
        """
        获取游戏单子详情 LevelOrderDetail
        参数:
            OrderID: 订单ID
            UserID: 用户ID
            Token: 认证token
        返回:
            dict: 游戏单子详情 LevelOrderDetail 响应数据
        
        注意:
            1. OrderID 为游戏订单ID
        """
        params = {
            'Action': 'LevelOrderDetail',
        }

        data = {
            'ODSerialNo': OrderID,
            'IsPublish': '0',
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        # 判断 response 有没有 Result 字段
        if "Result" not in response:
            # 没有 Result 字段，说明正常有数据
            response["code"] = 0
            response["message"] = "正常"
        else:
            # 有 Result 字段，说明有错误
            response["code"] = 1
            response["message"] = response["Err"]
        return response

    # 获取我接受的订单 LevelOrderMyList
    def LevelOrderMyList(self, UserID, Token):
        params = {
            'Action': 'LevelOrderMyList',
        }
        data = {
            'Publish': '0',
            'Status': '0',
            'CancelStatus': '0',
            'GameID': '0',
            'OverDays': '99',
            'SearchStr': '',
            'PageIndex': '1',
            'PageSize': '20',
            'GameMobile': '',
            'WithTG': '0',
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        
        return response 

    # 发布订单 - 王者荣耀版 LevelOrderAdd
    def LevelOrderAdd_WZRY(self, Title, Price, TimeLimit, Ensure1, Ensure2, GameMobile, PayPass, UID, game_account, game_password, game_athor_name,zone_server_ID, Order_Description, Token, UserID):
        Actors = self.spider_common_utils.base64_handle(f"{game_account}|*|{game_password}|*|{game_athor_name}|*|英雄数量个|*|{Order_Description}")
        params = {
            'Action': 'LevelOrderAdd',
        }
        ZoneServerID = {
            "安卓QQ": "107103017095500",
            "安卓微信": "107103117095600",
            "苹果QQ": "107103217095700",
            "苹果微信": "107103317095800",
        }
        data = {
            'ZoneServerID': ZoneServerID[zone_server_ID], # 发布的平台
            'Title': Title, # 订单标题
            'Price': Price, # 订单价格
            'TimeLimit': TimeLimit, # 订单时间限制,比如3，就是3个小时内
            'Ensure1': Ensure1, # 订单保证金
            'Ensure2': Ensure2, # 订单安全金
            'GameMobile': GameMobile, # 号主联系方式
            'PayPass': self.spider_common_utils.md5_encrypt(self.spider_common_utils.md5_encrypt(PayPass) + UID),
            'Mobile': '',
            'QQ': '',
            'LimitAccept': '0',
            'BasePrice': '0',
            'Label1': '',
            'Label2': '',
            'Memo': '',
            'Groups': 'OTHER',
            'Actors': Actors,
            'Members': '',
            'ReCode': '',
            'OverPrice': '',
            'LevelType2': '14',
            'Insurance': '0',
            'MaxClaimAmount': '20',
            'OrderType': '0',
            'NonceStr': '',
            'ExtStr': '{"ID":4,"IsEnable":1,"Content":"%s","Mode":0,"Data":[],"YSData":[]}' % Order_Description,
            'ReceiveOrderSetInfoId': '0',
            'IsMerchant': '0',
            'IsNeedExtraDeposit': '0',
            'TransTime': '0',
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        if response["Result"] == 1:
            # 正常
            response["code"] = 0
            response["message"] = "正常"
        else:
            # 有 Result 字段，说明有错误
            response["code"] = 1
            response["message"] = response["Err"]
        return response


    # 取消订单 - 王者荣耀版 LevelOrderDelSelf
    def LevelOrderDelSelf(self, OrderID, Token, UserID, Reason="感谢支持,现在不需要了,等太久了"):
        params = {
            'Action': 'LevelOrderDelSelf',
        }
        data = {
            'ODSerialNo': OrderID,
            'Reason': Reason,
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        if response["Result"] == 1:
            # 正常
            response["code"] = 0
            response["message"] = response["Err"]
        else:
            # 有 Result 字段，说明有错误
            response["code"] = 1
            response["message"] = response["Err"]
        return response


    # 接收订单
    def receive_order(self, order_id, PayPass, UID, Token, UserID):

        # 订单详情
        order_detail = self.LevelOrderDetail(order_id, UserID=UserID, Token=Token)
        if order_detail["code"] != 0:
            return order_detail
        params = {
            'Action': 'NewLevelOrderAccept',
        }
        
        data = {
            'ODSerialNo': order_id,
            'Stamp': str(order_detail["Stamp"]),
            'PayPass': self.spider_common_utils.md5_encrypt(self.spider_common_utils.md5_encrypt(PayPass) + UID),
            'Insurance': '0',
            'MaxClaimAmount': '0',
            'VisitType': '0',
            'NonceStr': '',
            'NoEnsure': '0',
            'IsWx': '0',
            'SourceType': '0',
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.4',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        return response


    # 搜索订单是否存在
    def search_order(self, order_id, Token, UserID):
        params = {
            'Action': 'LevelOrderList',
        }

        data = {
            'IsPub': '0',
            'GameID': '107',
            'ZoneID': '0',
            'ServerID': '0',
            'SearchStr': order_id,
            'STier': '',
            'ETier': '',
            'Sort_Str': '',
            'PageIndex': '1',
            'PageSize': '20',
            'Price_Str': '',
            'PubCancel': '0',
            'SettleHour': '0',
            'FilterType': '0',
            'PGType': '0',
            'Focused': '-1',
            'OrderType': '0',
            'PubRecommend': '0',
            'Score1': '0',
            'Score2': '0',
            'UserID': UserID,
            'TimeStamp': str(int(time.time())),
            'Ver': '1.0',
            'AppVer': '5.1.5',
            'AppOS': 'WebApp IOS',
            'AppID': 'webapp',
            'Sign': '',
        }
        data["Sign"] = self.md5_encrypt(data, e=params["Action"], Token=Token)

        response = requests.post(self.dailiantong_base_url, params=params, headers=self.headers, data=data).json()
        return response



if __name__ == "__main__":
    dailiantong_spider = DaiLianTongSpider()
    token = "E042506081BA410298F6858343416BB8"
    print(dailiantong_spider.get_auth_token(mobile="15346607104", password="dzyDZY12@"))
    # Order_Description = "1、未经同意请勿动用账号点券、物品，不要联系或回复好友信息2、切勿使用外挂，不允许打广告、挂机、恶意骂人等恶意行为"
    # response = dailiantong_spider.LevelOrderAdd_WZRY(
    #     Title="王者1-王者90",
    #     Price="2",
    #     TimeLimit="3",
    #     Ensure1="1",
    #     Ensure2="1",
    #     GameMobile="18171759943",
    #     PayPass="128524",
    #     UID="USR2025092602816",
    #     game_account="123456",
    #     game_password="123456",
    #     game_athor_name="yyyyy",
    #     Order_Description=Order_Description,
    #     Token=token,
    #     UserID="24118112",
    # )
    # 取消订单
    # response = dailiantong_spider.LevelOrderDelSelf(
    #     OrderID="10718137688496295476",
    #     Token=token,
    #     UserID="24118112",
    # )
